#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from flask import request
from flask_restx import Resource, fields
from app.api.admin.v1 import api
from app.services.dictionary_service import DictionaryService
from app.utils.auth import token_required


# 创建命名空间
ns = api.namespace('dictionaries', description='字典管理接口')


# 响应函数
def success_response(data=None, message='操作成功', code=200):
    return {'code': code, 'message': message, 'data': data}, code

def error_response(message='操作失败', code=400, data=None):
    return {'code': code, 'message': message, 'data': data}, code


# 定义请求和响应模型
dict_category_model = api.model('DictCategory', {
    'id': fields.Integer(description='分类ID'),
    'dict_name': fields.String(required=True, description='字典名称', example='性别'),
    'dict_code': fields.String(required=True, description='字典编码', example='gender'),
    'sort_order': fields.Integer(description='排序', example=1),
    'remark': fields.String(description='备注'),
    'is_active': fields.Boolean(description='是否有效', example=True),
    'item_count': fields.Integer(description='字典项数量'),
    'create_time': fields.String(description='创建时间'),
    'update_time': fields.String(description='更新时间')
})

dict_category_create_model = api.model('DictCategoryCreate', {
    'dict_name': fields.String(required=True, description='字典名称', example='性别'),
    'dict_code': fields.String(required=True, description='字典编码', example='gender'),
    'sort_order': fields.Integer(description='排序', example=1),
    'remark': fields.String(description='备注', example='用户性别选项'),
    'is_active': fields.Boolean(description='是否有效', example=True)
})

dict_item_model = api.model('DictItem', {
    'id': fields.Integer(description='字典项ID'),
    'dict_id': fields.Integer(description='字典分类ID'),
    'dict_code': fields.String(description='字典编码'),
    'dict_name': fields.String(description='字典名称'),
    'item_name': fields.String(required=True, description='项名称', example='女'),
    'item_value': fields.String(required=True, description='数据值', example='2'),
    'sort_order': fields.Integer(description='排序', example=1),
    'is_active': fields.Boolean(description='是否有效', example=True),
    'remark': fields.String(description='备注'),
    'create_time': fields.String(description='创建时间'),
    'update_time': fields.String(description='更新时间')
})

dict_item_create_model = api.model('DictItemCreate', {
    'dict_id': fields.Integer(required=True, description='字典分类ID', example=1),
    'item_name': fields.String(required=True, description='项名称', example='女'),
    'item_value': fields.String(required=True, description='数据值', example='2'),
    'sort_order': fields.Integer(description='排序', example=1),
    'is_active': fields.Boolean(description='是否有效', example=True),
    'remark': fields.String(description='备注', example='女性选项')
})

pagination_model = api.model('Pagination', {
    'page': fields.Integer(description='当前页码'),
    'per_page': fields.Integer(description='每页数量'),
    'total': fields.Integer(description='总数量'),
    'pages': fields.Integer(description='总页数')
})

category_list_response_model = api.model('CategoryListResponse', {
    'code': fields.Integer(description='状态码'),
    'message': fields.String(description='响应消息'),
    'data': fields.Nested(api.model('CategoryListData', {
        'list': fields.List(fields.Nested(dict_category_model)),
        'pagination': fields.Nested(pagination_model)
    }))
})

item_list_response_model = api.model('ItemListResponse', {
    'code': fields.Integer(description='状态码'),
    'message': fields.String(description='响应消息'),
    'data': fields.Nested(api.model('ItemListData', {
        'list': fields.List(fields.Nested(dict_item_model)),
        'pagination': fields.Nested(pagination_model)
    }))
})


@ns.route('/categories')
class DictCategoryListResource(Resource):
    @ns.doc('get_dict_categories', security='Bearer')
    @ns.marshal_with(category_list_response_model)
    @ns.param('page', '页码', type=int, default=1)
    @ns.param('per_page', '每页数量', type=int, default=10)
    @ns.param('keyword', '搜索关键字', type=str)
    @token_required
    def get(self, current_admin):
        """获取字典分类列表"""
        try:
            page = int(request.args.get('page', 1))
            per_page = int(request.args.get('per_page', 10))
            keyword = request.args.get('keyword', '')
            
            result = DictionaryService.get_categories(page, per_page, keyword)
            return success_response(result, '获取成功')
        except Exception as e:
            return error_response(f'获取失败: {str(e)}', 500)
    
    @ns.doc('create_dict_category', security='Bearer')
    @ns.expect(dict_category_create_model)
    @token_required
    def post(self, current_admin):
        """新增字典分类"""
        try:
            data = request.get_json()
            category = DictionaryService.create_category(data)
            return success_response(category.to_dict(), '创建成功', 201)
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'创建失败: {str(e)}', 500)


@ns.route('/categories/<int:category_id>')
class DictCategoryResource(Resource):
    @ns.doc('get_dict_category', security='Bearer')
    @token_required
    def get(self, current_admin, category_id):
        """获取字典分类详情"""
        try:
            category = DictionaryService.get_category_by_id(category_id)
            if not category:
                return error_response('字典分类不存在', 404)
            return success_response(category.to_dict())
        except Exception as e:
            return error_response(f'获取失败: {str(e)}', 500)
    
    @ns.doc('update_dict_category', security='Bearer')
    @ns.expect(dict_category_create_model)
    @token_required
    def put(self, current_admin, category_id):
        """更新字典分类"""
        try:
            data = request.get_json()
            category = DictionaryService.update_category(category_id, data)
            return success_response(category.to_dict(), '更新成功')
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'更新失败: {str(e)}', 500)
    
    @ns.doc('delete_dict_category', security='Bearer')
    @token_required
    def delete(self, current_admin, category_id):
        """删除字典分类"""
        try:
            DictionaryService.delete_category(category_id)
            return success_response(message='删除成功')
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'删除失败: {str(e)}', 500)


@ns.route('/categories/options')
class DictCategoryOptionsResource(Resource):
    @ns.doc('get_dict_category_options', security='Bearer')
    @token_required
    def get(self, current_admin):
        """获取字典分类选项（用于下拉选择）"""
        try:
            options = DictionaryService.get_active_categories()
            return success_response(options)
        except Exception as e:
            return error_response(f'获取失败: {str(e)}', 500)


@ns.route('/items')
class DictItemListResource(Resource):
    @ns.doc('get_dict_items', security='Bearer')
    @ns.marshal_with(item_list_response_model)
    @ns.param('dict_id', '字典分类ID', type=int)
    @ns.param('page', '页码', type=int, default=1)
    @ns.param('per_page', '每页数量', type=int, default=10)
    @ns.param('keyword', '搜索关键字', type=str)
    @token_required
    def get(self, current_admin):
        """获取字典项列表"""
        try:
            dict_id = request.args.get('dict_id', type=int)
            page = int(request.args.get('page', 1))
            per_page = int(request.args.get('per_page', 10))
            keyword = request.args.get('keyword', '')
            
            result = DictionaryService.get_items(dict_id, page, per_page, keyword)
            return success_response(result, '获取成功')
        except Exception as e:
            return error_response(f'获取失败: {str(e)}', 500)
    
    @ns.doc('create_dict_item', security='Bearer')
    @ns.expect(dict_item_create_model)
    @token_required
    def post(self, current_admin):
        """新增字典项"""
        try:
            data = request.get_json()
            item = DictionaryService.create_item(data)
            return success_response(item.to_dict(), '创建成功', 201)
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'创建失败: {str(e)}', 500)


@ns.route('/items/<int:item_id>')
class DictItemResource(Resource):
    @ns.doc('get_dict_item', security='Bearer')
    @token_required
    def get(self, current_admin, item_id):
        """获取字典项详情"""
        try:
            item = DictionaryService.get_item_by_id(item_id)
            if not item:
                return error_response('字典项不存在', 404)
            return success_response(item.to_dict())
        except Exception as e:
            return error_response(f'获取失败: {str(e)}', 500)
    
    @ns.doc('update_dict_item', security='Bearer')
    @ns.expect(dict_item_create_model)
    @token_required
    def put(self, current_admin, item_id):
        """更新字典项"""
        try:
            data = request.get_json()
            item = DictionaryService.update_item(item_id, data)
            return success_response(item.to_dict(), '更新成功')
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'更新失败: {str(e)}', 500)
    
    @ns.doc('delete_dict_item', security='Bearer')
    @token_required
    def delete(self, current_admin, item_id):
        """删除字典项"""
        try:
            DictionaryService.delete_item(item_id)
            return success_response(message='删除成功')
        except ValueError as e:
            return error_response(str(e), 400)
        except Exception as e:
            return error_response(f'删除失败: {str(e)}', 500)


@ns.route('/items/by-code/<string:dict_code>')
class DictItemsByCodeResource(Resource):
    @ns.doc('get_dict_items_by_code', security='Bearer')
    @ns.param('active_only', '只获取有效项', type=bool, default=True)
    @token_required
    def get(self, current_admin, dict_code):
        """根据字典编码获取字典项列表"""
        try:
            active_only = request.args.get('active_only', 'true').lower() == 'true'
            items = DictionaryService.get_items_by_code(dict_code, active_only)
            return success_response(items)
        except Exception as e:
            return error_response(f'获取失败: {str(e)}', 500)


# 将命名空间注册到统一的API实例
api.add_namespace(ns, path='/dictionaries') 